package jude.java.money.migrate;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jude.java.money.tools.Tidy;
import jude.java.util.Utils;

import org.apache.commons.lang.StringUtils;

public class FieldHandlers {
	private static final String DEFAULT = FieldHandlers.class.getName();
	
	/** 将所有首字母大写 */
	public static Handler CAPITALIZE_HANDLER = new Handler() {
		@Override
		public String handle(String o, String name, String sku, Object extra) {
			return StringUtils.capitalize(o);
		}
	};
	
	public static final Handler GENDER_HANDLER = new Handler() {
		/**
		 * @param extra 为产品分类
		 */
		@Override
		public String handle(String o, String name, String sku, Object extra) {
			boolean c = extra instanceof String;
			String e = c ? (String)extra : null;
			if (name.matches(".*\\b[Ww]omen\\b.*") || c && e.matches(".*\\b[Ww]omen\\b.*"))
				return "Women";
			if (name.matches(".*\\b[Mm]en\\b.*") || c && e.matches(".*\\b[Mm]en\\b.*"))
				return "Men";
			if (name.matches(".*\\b[K]ids?\\b.*") || c && e.matches(".*\\b[Kk]ids?\\b.*"))
				return "Kids";
			if (name.matches(".*\\[Hh]igh [Hh]eels?\\b") || c && e.matches(".*\\[Hh]igh [Hh]eels?\\b.*"))
				return "Women";
			return null;
		}};
	
	public static final Handler ATTRIBUTE_SKU_HANDLER = new Handler() {
		@Override
		public String handle(String o, String name, String sku, Object category) {
			Pattern p = Pattern.compile("\\b(us[\\s\\-]?\\d{1,2}(\\.\\d)?)\\b", Pattern.CASE_INSENSITIVE);
			Matcher m = p.matcher(o);
			if (m.find()) {
				return m.group(1).toLowerCase().replace('.', '_');
			}
			return o;
		}
	};
	
	public static final Handler HTML_TO_TEXT_HANDLER = new Handler() {
		@Override
		public String handle(String o, String name, String sku, Object extra) {
			return Tidy.html2text(o);
		}
	};
	
	public static final Handler REMOVE_LINK_HANDLER = new Handler() {
		@Override
		public String handle(String o, String name, String sku, Object extra) {
			return Tidy.removeLinks(o);
		}
	};
	
	private Map<String, _Handler<?>> handlers;
	
	public FieldHandlers() {
		handlers = new HashMap<String, _Handler<?>>();
	}
	public FieldHandlers(Handler handler) {
		this();
		handlers.put(DEFAULT, handler);
	}
	public FieldHandlers(String key, Handler handler) {
		this();
		handlers.put(key, handler);
	}
	
	/**
	 * @param key 字段标识
	 * @param str 原值
	 * @param name 产品名称
	 * @param sku 产品SKU
	 * @param extra 产品分类或其它属性, 不同字段各自定义
	 */
	public String handle(String key, String str, String name, String sku, Object extra) {
		_Handler<?> h = get(key);
		if (h instanceof Handler)
			return ((Handler)h).handle(str, name, sku, extra);
		return str;
	}
	
	public String[] handleEx(String key, String str, String name, String sku, String extra) {
		_Handler<?> h = get(key);
		if (h instanceof HandlerEx)
			return ((HandlerEx)h).handle(str, name, sku, extra);
		else if (h instanceof Handler)
			str = ((Handler)h).handle(str, name, sku, extra);
		return new String[] {str};
	}
	
	
	public String handle(String key, String str) {
		return handle(key, str, null, null, null);
	}
	
	public FieldHandlers add(String key, Handler handler) {
		handlers.put(key, handler);
		return this;
	}
	public FieldHandlers add(String key, HandlerEx handler) {
		handlers.put(key, handler);
		return this;
	}
	
	public FieldHandlers add(String key, final String regex, final String replace) {
		add(key, new Handler() {
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				return o.replaceAll(regex, replace);
			}
		});
		return this;
	}
	
	@SuppressWarnings("unchecked")
	public <T> _Handler<T> get(String key) {
		return (_Handler<T>)handlers.get(key);
	}
	
	/** 
	 * 提取出正则匹配的最后一组数据
	 * @param tip 是否提示匹配的字符串
	 * @param regexes 正则, 按顺序查找
	 * */
	public static Handler simplifyHandler(final boolean tip, final String... regexes) {
		return new Handler() {
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				for (int i = 0; i < regexes.length; i++) {
					Pattern p = Pattern.compile(regexes[i]);
					Matcher m = p.matcher(o);
					if (m.find()) {
						return m.group(m.groupCount());
					}
				}
				if (tip)
					System.out.println(o + " not matched");
				return o;
			}
		};
	}
	
	public static Handler simplifyHandler(final String... regexes) {
		return simplifyHandler(false, regexes);
	}
	
	/** 移除某些关键键字 */
	public static Handler trimHandler(final String... keys) {
		return new Handler() {
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				String s = o;
				for (int i = 0; i < keys.length; i++) {
					if(o.startsWith(keys[i])) {
						o = o.substring(keys[i].length()).trim();
					}
					if(o.endsWith(keys[i])) {
						o = o.substring(0, o.length() - keys[i].length()).trim();
					}
//					o = StringUtils.remove(o, keys[i]);
				}
				o = o.trim();
				if (o.isEmpty()) {
					System.out.println(s + " is empty after clear");
					return s;
				}
				if (!o.equals(s))
					System.out.println(s + " => " + o);
				return o;
			}
		};
	}
	
	public static Handler renameImageHandler(final String path, final boolean rename) {
		return new Handler() {
			private String path2 = path;
			
			/** @param extra 为图片序号 */
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				if (path2 == null && !rename)
					return o;
				String fileName = new File(o).getName();
				String path = path2;
				if (path2 == null) {
					path = o.substring(0, o.length() - fileName.length());
				}
				path = Utils.wrap(path, "/");
				if (rename) {
					String ext = fileName.substring(fileName.lastIndexOf('.') + 1);
					if (extra == null || Utils.getInteger((String)extra, -1) == -1)
						return path + (sku + "." + ext).toLowerCase();
					return path + (sku + "_" + StringUtils.leftPad((String)extra, 2, '0') + "." + ext).toLowerCase();
				}
				return path + fileName;
			}
		};
	}
	
	/**
	 * 除了将原来的分类归到新的分类(合并, 改名), 还可以将产品增加到额外的分类中
	 * @param categories 新的分类, 以/开头的表示根分类
	 * @param categoryGroups 原来的分类
	 * @param extraGroup 额外分类
	 * */
	public static HandlerEx groupHandler(final String[] categories, final String[][] categoryGroups, final String[][] extraGroup) {
		return new HandlerEx() {
			@Override
			public String[] handle(String o, String name, String sku, Object extra) {
				List<String> r = new ArrayList<String>();
				if (categories.length != categoryGroups.length) {
					System.out.println("the size is different");
					r.add(o);
					return toArray(r);
				}
				int k = -1;
				for (int i = 0; i < categoryGroups.length; i++) {
					if (Utils.in(o, categoryGroups[i])) {
						r.add(categories[i]);
						k = i;
						break;
					}
				}
				if (k == -1) {
					r.add(o);
					return toArray(r);
				}
				if (extraGroup != null && extraGroup.length > k && extraGroup[k] != null) {
					for (int j = 0; j < extraGroup[k].length; j++) {
						r.add(extraGroup[k][j]);
					}
				}
				return toArray(r);
			}
		};
	}
	
	/** @see #groupHandler(String[], String[][], String[][]) */
	public static Handler groupHandler(final String[] categories, final String[][] categoryGroups) {
		return new Handler() {
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				if (categories.length != categoryGroups.length) {
					System.out.println("the size is different");
					return o;
				}
				for (int i = 0; i < categoryGroups.length; i++) {
					if (Utils.in(o, categoryGroups[i]))
						return categories[i];
				}
				return o;
			}
		};
	}
	
	public static Handler idHandler(final String prefix, final int start) {
		return new Handler() {
			private String prefix2 = prefix;
			private int start2 = start;
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				return prefix2 + (start2 ++);
			}
		};
	}
	
	public static Handler urlkeyHandler(final String prefix) {
		return new Handler() {
			private String prefix2 = Utils.wrapRight(prefix, "/");
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				String c = (name+"-" + sku).replaceAll("[^\\w_]+", "_");
				c = c.replaceAll("_+", "-").toLowerCase();
				if (prefix2 != null) {
					c = prefix2 + c;
				}
				return c;
			}
		};
	}
	
	public static Handler replaceHandler(final String[] pairs) {
		return new Handler() {
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				
				return null;
			}
		};
	}
	
	public static Handler multiHandler(final Handler... handlers) {
		return new Handler() {
			@Override
			public String handle(String o, String name, String sku, Object extra) {
				for (int i = 0; i < handlers.length; i++) {
					o = handlers[i].handle(o, name, sku, extra);
				}
				return o;
			}
			
		};
	}
	
	private interface _Handler<T> {
		/**
		 * @param o 原值
		 * @param name 产品名称
		 * @param sku 产品SKU
		 * @param extra 产品分类或其它属性, 不同字段各自定义
		 */
		public T handle(String o, String name, String sku, Object extra);
	}
	
	public interface Handler extends _Handler<String> {
	}
	public interface HandlerEx extends _Handler<String[]> {
	}
	public static final String[] toArray(List<String> r) {
		return r.toArray(new String[r.size()]);
	}

}
